import os
import random
import time
import threading
import pygame
from datetime import datetime, time as dt_time, timedelta, date
import schedule
import chinese_calendar as calendar

# 配置
MUSIC_FOLDER = "D:/auto-play-music/MP3"  # MP3文件夹路径
PLAY_DURATION = 5 * 60  # 总播放时长（5分钟）

# 定义播放时间段 (开始时间)
PLAY_SCHEDULES = [
    dt_time(14, 00),  # 10:25
    dt_time(10, 0),  # 10:00
    dt_time(15, 0),  # 15:00
]

def is_today_workday():
    today = datetime.now().date()
    # today = date(2025, 10, 1)
    return calendar.is_workday(today)

def get_all_music_files():
    """获取D盘MP3文件夹下所有音乐文件"""
    if not os.path.exists(MUSIC_FOLDER):
        print(f"错误：文件夹不存在 - {MUSIC_FOLDER}")
        return []

    music_files = []
    for root, _, files in os.walk(MUSIC_FOLDER):
        for file in files:
            if file.lower().endswith('.mp3'):
                music_files.append(os.path.join(root, file))

    if not music_files:
        print("警告：未找到MP3文件！")
        return []

    return music_files


def play_random_music(scheduled_end_time=None):
    # 判断当前日期是不是工作日
    today_str = datetime.now().strftime('%Y-%m-%d')
    if not is_today_workday():
        print(f"\n今天是 {today_str}，属于节假日或周末，程序将保持运行但不播放音乐")
        return
    print(f"\n今天是 {today_str}，属于工作日，程序将播放音乐")
    """
    随机播放音乐
    :param scheduled_end_time: 预定的结束时间（datetime对象）
    """
    music_files = get_all_music_files()
    if not music_files:
        return

    # 初始化音频系统
    pygame.mixer.init()
    played_indices = set()  # 记录已播放的歌曲索引

    def play_next():
        """随机选择一首未播放的歌曲"""
        if len(played_indices) >= len(music_files):
            print("所有歌曲已播放一遍，重新开始随机选择")
            played_indices.clear()

        available_indices = [i for i in range(len(music_files)) if i not in played_indices]
        if not available_indices:
            return

        current_index = random.choice(available_indices)
        played_indices.add(current_index)

        print(f"{datetime.now().strftime('%H:%M:%S')} - 正在播放: {os.path.basename(music_files[current_index])}")
        pygame.mixer.music.load(music_files[current_index])
        pygame.mixer.music.play()

    # 计算剩余播放时间
    if scheduled_end_time:
        remaining_time = (scheduled_end_time - datetime.now()).total_seconds()
        if remaining_time <= 0:
            print("预定结束时间已过，不播放")
            return
    else:
        remaining_time = PLAY_DURATION

    # 播放第一首随机歌曲
    play_next()

    # 创建停止线程
    def stop_playback():
        pygame.mixer.music.stop()
        print(f"{datetime.now().strftime('%H:%M:%S')} - 播放已停止")

    # 在预定结束时间停止
    stop_timer = threading.Timer(remaining_time, stop_playback)
    stop_timer.daemon = True
    stop_timer.start()

    # 监听播放状态
    end_time = time.time() + remaining_time
    while time.time() < end_time:
        if not pygame.mixer.music.get_busy():
            play_next()
        time.sleep(0.1)

    # 确保停止
    pygame.mixer.music.stop()


def check_missed_schedules():
    """检查是否有错过的播放时间段（当前时间仍在5分钟窗口内）"""
    now = datetime.now()
    for schedule_time in PLAY_SCHEDULES:
        schedule_dt = datetime.combine(now.date(), schedule_time)
        scheduled_end_time = schedule_dt + timedelta(minutes=5)

        # 如果当前时间在计划时间后的5分钟内（且未超过结束时间）
        if schedule_dt <= now <= scheduled_end_time:
            print(f"检测到延迟启动，当前时间在 {schedule_time.strftime('%H:%M')} 的播放窗口内")
            print(f"立即开始播放，将在预定的结束时间 {scheduled_end_time.time().strftime('%H:%M:%S')} 停止")
            play_random_music(scheduled_end_time)
            break


def schedule_checker():
    """定时任务检查"""
    # 首次启动时检查是否有错过的播放
    check_missed_schedules()

    # 然后正常执行定时检查
    while True:
        schedule.run_pending()
        time.sleep(1)


if __name__ == "__main__":
    print("随机音乐播放器已启动")
    print(f"音乐文件夹: {MUSIC_FOLDER}")
    print("播放时间段:")
    for t in PLAY_SCHEDULES:
        print(
            f"  - {t.strftime('%H:%M')} 到 {(datetime.combine(datetime.today(), t) + timedelta(minutes=5)).time().strftime('%H:%M')}")

    # 初始化pygame（仅音频）
    pygame.mixer.init()

    # 定时任务
    for schedule_time in PLAY_SCHEDULES:
        schedule.every().day.at(schedule_time.strftime("%H:%M")).do(
            lambda st=schedule_time: play_random_music(
                datetime.combine(datetime.today(), st) + timedelta(minutes=5)
            )
        )

    # 启动定时任务线程
    threading.Thread(target=schedule_checker, daemon=True).start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        pygame.mixer.music.stop()
        print("\n播放器已关闭")
